#include <rtthread.h>
#include <rtdevice.h>
#include <oled/oled.h>
#include <shell.h>
#include "../msg.h"

typedef struct {
    uint8_t* buffer;
    int width;
    int height;
    int size;
} bmp_t;

const uint8_t msg_rep_success[] = {
    0x00
};

const uint8_t msg_rep_retry[] = {
    0x01
};

rt_mailbox_t msg_mb = RT_NULL;

void show_bmp(bmp_t* bmp)
{
    Oled* oled = Oled::getInstance();
    oled->drawXBMP(0, 0, bmp->width, bmp->height, bmp->buffer);
    oled->sendBuffer();
}


void video_msg_server(void* parameter)
{
    uint8_t id;
    bmp_t* bmp;
    int ret = 0;
    int is_start = 0;
    while (1)
    {
        bmp = (bmp_t*)rt_malloc(sizeof(bmp_t));
        bmp->height = 64;
        bmp->width = 128;
        bmp->size = bmp->height * bmp->width / 8;
        bmp->buffer = (uint8_t*)rt_malloc(bmp->size);
retry:

        ret = msg_receive_request((rt_device_t)parameter, &id, bmp->buffer, bmp->size);
        if (ret != MSG_TRANSFER_DONE)
        {
            if (is_start != 0)
            {
                msg_send_response((rt_device_t)parameter, id, (uint8_t*)msg_rep_retry, sizeof(msg_rep_retry));
                //rt_kprintf("send response:retry\n");
            }
            goto retry;
        }
        is_start = 1;
        msg_send_response((rt_device_t)parameter, id, (uint8_t*)msg_rep_success, sizeof(msg_rep_success));
        ret = rt_mb_send(msg_mb, (uint32_t)bmp);
        rt_thread_mdelay(1);
        //rt_kprintf("send response\n");
    }
}

static void video_play(int argc,char *argv[])
{
    bmp_t* bmp;
    int ret = 0;
    int i = 0;
    rt_device_t uart = rt_device_find("uart2");
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;  /* 初始化配置参数 */

    /* step2：修改串口配置参数 */
    config.baud_rate = BAUD_RATE_230400;        //修改波特率为 9600
    config.data_bits = DATA_BITS_8;           //数据位 8
    config.stop_bits = STOP_BITS_1;           //停止位 1
    config.bufsz     = 4096;                   //修改缓冲区 buff size 为 128
    config.parity    = PARITY_NONE;           //无奇偶校验位

    /* step3：控制串口设备。通过控制接口传入命令控制字，与控制参数 */
    rt_device_control(uart, RT_DEVICE_CTRL_CONFIG, &config);

    rt_device_open(uart, RT_DEVICE_FLAG_INT_RX);
    Oled* oled = Oled::getInstance();
    oled->clearBuffer();
    msg_mb = rt_mb_create("msg", 3, RT_IPC_FLAG_FIFO);
    rt_thread_t tid = rt_thread_create("msg", video_msg_server, uart, 2048, 10, 1);
    rt_thread_startup(tid);

    while (1)
    {
        ret = rt_mb_recv(msg_mb, (uint32_t*)&bmp, 100);
        if (ret < 0)
        {
            //rt_kprintf("receive mb error:%d\n", ret);
            continue;
        }
        i++;
        rt_kprintf("frame:%d\n", i);
        show_bmp(bmp);

        rt_free(bmp->buffer);
        rt_free(bmp);
    }

    rt_thread_delete(tid);
    rt_mb_delete(msg_mb);
    rt_free(bmp->buffer);
}
MSH_CMD_EXPORT(video_play, play stream video);

